Add stale-while-revalidate support with on_stale refresh hook#139
Open
matthutchinson wants to merge 1 commit intosourcelevel:masterfrom
Open
Conversation
…ook to trigger refresh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Cache-Control: stale-while-revalidate=<seconds>directive so stale cache entries can still be served during a bounded grace window.:on_stalecallback hook (proc.call(request:, env:, cached_response:)) that runs when a stale response is served, enabling callers to trigger asynchronous cache refreshes.Related issue: #84
Why
Today, once a cached response becomes stale, the middleware must synchronously revalidate it before responding. That is correct for strict freshness, but it can increase latency and reduce resiliency for endpoints where slightly stale data is acceptable.
stale-while-revalidateis a standard HTTP cache directive that allows a better tradeoff:See this explanation for more info, and this diagram.
This PR adds that behavior while preserving existing semantics for non-SWR responses.
How it works
1) Parse SWR directive
Faraday::HttpCache::CacheControlnow exposes#stale_while_revalidate.2) Determine SWR eligibility
Faraday::HttpCache::Responsenow exposes:#stale_while_revalidate?→ true when response is stale but still inside SWR window,#stale_while_revalidate→ parsed grace window in seconds.3) Middleware request flow
Faraday::HttpCachenow accepts:on_stale(or an equivalent init block).#process, behavior is now::stale, invokeon_stalecallback,must_revalidatepath (unchanged).4) Callback contract
When serving a stale response in the SWR window, middleware invokes:
on_stale.call(request:, env:, cached_response:)request:Faraday::HttpCache::Requestenv: currentFaraday::Envcached_response:Faraday::HttpCache::ResponseCallback errors are rescued and logged, so they do not break response serving.
5) Instrumentation/logging
:staleto cache statuses so instrumentation can distinguish SWR-served requests from fresh/valid hits.Tests
Added/updated coverage for:
CacheControlSWR parsing,:stale.Also added test server endpoints to exercise SWR flows.
Docs and example
:on_staleusage and callback arguments,:staleinstrumentation status.examples/stale_while_revalidate.rbdemonstrating stale serving and background refresh triggering.Unreleased.Backward compatibility
:on_stalearg is optionalstale-while-revalidateis not present.